package com.jellyfishumbrella;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import be.humphreys.simplevoronoi.Cell;
import be.humphreys.simplevoronoi.GraphEdge;
import be.humphreys.simplevoronoi.LandscapeSite;
import be.humphreys.simplevoronoi.Voronoi;
import be.humphreys.simplevoronoi.VoronoiOutput;


import com.jellyfishumbrella.noise.Noise;

public class LandscapeData_OLD {
	public double					borderRadius	= 100 * GameLogic.SCALING;
	private Voronoi					voronoi;
	double							numBorderSites	= 10;
	int								landscapePoints;
	VoronoiInput					baseSites;
	VoronoiOutput					rawOutput;
	Random							r				= new Random();
	private static long				SEED			= 18;
	private static Noise			n				= new Noise(SEED, 10000);
	public HashMap<Site, Cell>		cells;
	HashMap<Site, Cell>				landCells;
	HashMap<Site, Cell>				waterCells;
	public HashMap<String, Corner>	allCorners		= new HashMap<String, Corner>();
	ArrayList<Corner>				drawCorners		= new ArrayList<Corner>();
	public double					maxAlt			= 0;

	short							allCornerIndex	= 0;

	public LandscapeData_OLD() {
		SEED = 18;// new Date().getTime();
		n = new Noise(SEED, 1000);
	}

	public void createlandscape(double borderRadius, int landscapePoints) {
		this.borderRadius = borderRadius;
		this.landscapePoints = landscapePoints;

		voronoi = new Voronoi(0.01);

		synchronized (voronoi) {
			baseSites = new VoronoiInput<LandscapeSite>();

			createBorderSites(numBorderSites, true);
			createIslandSites(landscapePoints);

			rawOutput = voronoi.generateVoronoi(baseSites, borderRadius);

			for (int i = 0; i < 30; i++) {
				populateCellsMap();
				relaxSites();
				rawOutput = voronoi.generateVoronoi(baseSites, borderRadius);
			}
			populateCellsMap();

			confirmCellEdgeLoops();
			
			mergeCornersAndEdges(0.001);
			
			confirmCellEdgeLoops();
			
			makeLandorWater();
			expandBorder();
			divideLandAndWater();
			applyElevations();
			determineDownHill();
			// placeRivers(30);

			populateAllCorners();

			double scaler = 0*5000.0 / maxAlt;

			scaleCornerElevations(scaler);
			elevateSites();

			makeGLTriangleFans();
			
			computeNormals();
			
			glScale();

			System.out.println(maxAlt);
		}
	}

	public void createBorderSites(double numBorderSites, boolean isRadial) {
		if (isRadial) {
			for (double angle = 0; angle < 360.0; angle += 360.0 / numBorderSites) {
				double X = borderRadius * Math.cos(Math.toRadians(angle));
				double Y = borderRadius * Math.sin(Math.toRadians(angle));
				LandscapeSite newSite = new LandscapeSite(X + r.nextDouble(), Y + r.nextDouble());
				// System.out.println(((Corner) newSite).toString());
				//newSite.alt = 0;
				newSite.isBorder = true;
				baseSites.add(newSite);
			}
		} else {
			for (double i = 0; i < numBorderSites; i++) {
				double xStep = i / (numBorderSites - 1.0);
				LandscapeSite newSite = new LandscapeSite(borderRadius * xStep + r.nextDouble() - borderRadius / 2.0, 0 + r.nextDouble() - borderRadius / 2.0);
				//newSite.alt = 0;
				newSite.isBorder = true;
				baseSites.add(newSite);
				newSite = new LandscapeSite(borderRadius * xStep + r.nextDouble() - borderRadius / 2.0, borderRadius + r.nextDouble() - borderRadius / 2.0);
				//newSite.alt = 0;
				newSite.isBorder = true;
				baseSites.add(newSite);
			}
			for (double j = 0; j < numBorderSites; j++) {
				double yStep = j / (numBorderSites - 1.0);
				LandscapeSite newSite = new LandscapeSite(0 + r.nextDouble() - borderRadius / 2.0, borderRadius * yStep + r.nextDouble() - borderRadius / 2.0);
				//newSite.alt = 0;
				newSite.isBorder = true;
				baseSites.add(newSite);
				newSite = new LandscapeSite(borderRadius + r.nextDouble() - borderRadius / 2.0, borderRadius * yStep + r.nextDouble() + r.nextDouble() - borderRadius / 2.0);
				//newSite.alt = 0;
				newSite.isBorder = true;
				baseSites.add(newSite);
			}
		}
		System.out.println("# of sites: " + baseSites.size());
	}

	public void createIslandSites(int steps) {
		for (int i = 0; i < steps; i++) {
			double X = borderRadius / 2.0 - r.nextDouble() * borderRadius;
			double Y = borderRadius / 2.0 - r.nextDouble() * borderRadius;
			double radius = Math.sqrt(X * X + Y * Y);
			if (radius < borderRadius * 0.75) {
				LandscapeSite newSite = new LandscapeSite(X + r.nextDouble(), Y + r.nextDouble());
				baseSites.add(newSite);
			}
		}
		System.out.println("# of sites: " + baseSites.size() + "    " + steps);
	}

	public void populateCellsMap() {
		cells = rawOutput.toCells();
	}

	public void alignNormals(){
		for (Map.Entry<Site, Cell> entry : cells.entrySet()) {
			Cell currCell = (Cell) entry.getValue();
			currCell.pointNormalsUp();
		}
	}
	
	public void relaxSites() {
		for (Map.Entry<Site, Cell> entry : cells.entrySet()) {
			LandscapeSite currSite = (LandscapeSite) entry.getKey();
			if (!currSite.isBorder) {
				Cell currCell = (Cell) entry.getValue();

				Site averageSite = new Site();
				double count = 0;
				for (int i = 0; i < currCell.edges.size(); i++) {
					GraphEdge currEdge = currCell.edges.get(i);
					averageSite.x += currEdge.corner1.x + currEdge.corner2.x;
					averageSite.y += currEdge.corner1.y + currEdge.corner2.y;
					count += 2.0;
				}
				averageSite.x /= count;
				averageSite.y /= count;
				currSite.x = averageSite.x;
				currSite.y = averageSite.y;
			}
		}
	}

	public void mergeCornersAndEdges(double grid) {
		HashMap<String, Corner> mergedCorners = new HashMap<String, Corner>();
		HashMap<String, GraphEdge> mergedEdges = new HashMap<String, GraphEdge>();
		cells = rawOutput.toCells();
		int cornerCounter = 0;
		int edgeCounter = 0;
		for (Map.Entry<Site, Cell> entry : cells.entrySet()) {
			Cell currCell = (Cell) entry.getValue();
			for (int i = 0; i < currCell.edges.size(); i++) {
				GraphEdge currEdge = currCell.edges.get(i);
				currEdge.corner1.snapToGrid(grid);
				currEdge.corner2.snapToGrid(grid);
				// System.out.println(currEdge.toString() +
				// "                             " + currEdge.corner1.toString()
				// + "," + currEdge.corner2.toString());
				if (mergedCorners.containsKey(currEdge.corner1.toString())) {
					currEdge.corner1 = mergedCorners.get(currEdge.corner1.toString());
				} else {
					mergedCorners.put(currEdge.corner1.toString(), currEdge.corner1);
				}
				if (mergedCorners.containsKey(currEdge.corner2.toString())) {
					currEdge.corner2 = mergedCorners.get(currEdge.corner2.toString());
				} else {
					mergedCorners.put(currEdge.corner2.toString(), currEdge.corner2);
				}
				cornerCounter += 2;
				if (mergedEdges.containsKey(currEdge.toString())) {
					currEdge = mergedEdges.get(currEdge.toString());
				} else {
					mergedEdges.put(currEdge.toString(), currEdge);
				}
				edgeCounter++;
			}
		}

		for (Map.Entry<Site, Cell> entry : cells.entrySet()) {
			Cell currCell = (Cell) entry.getValue();
			for (int i = 0; i < currCell.edges.size(); i++) {
				GraphEdge currEdge = currCell.edges.get(i);
				if (!currEdge.corner1.edges.contains(currEdge)) {
					currEdge.corner1.edges.add(currEdge);
				}
				if (!currEdge.corner2.edges.contains(currEdge)) {
					currEdge.corner2.edges.add(currEdge);
				}
			}
		}
		allCorners = new HashMap<String, Corner>();
		allCornerIndex = 0;
		for (Map.Entry<String, Corner> entry : mergedCorners.entrySet()) {
			Corner currCorner = (Corner) entry.getValue();
			currCorner.neighbors = currCorner.getNeighborCorners();
			if (allCorners.containsKey(currCorner.toString())) {
				currCorner.glID = allCorners.get(currCorner.toString()).glID;
				currCorner = allCorners.get(currCorner.toString());
			} else {
				currCorner.glID = allCornerIndex++;
				allCorners.put(currCorner.toString(), currCorner);
			}
		}
		System.out.println("Corners: " + cornerCounter + "   " + mergedCorners.size());
		System.out.println("Edges: " + edgeCounter + "   " + mergedEdges.size());
		System.out.println("allCorners: " + allCorners.size());
	}

	public void confirmCellEdgeLoops(){
		for (Map.Entry<Site, Cell> entry : cells.entrySet()) {
			Cell currCell = (Cell) entry.getValue();
			currCell.confirmEdgeLoop();
		}
	}
	
	public void makeLandorWater() {
		boolean isNoisy = true;
		// cells = rawOutput.toCells();
		for (Map.Entry<Site, Cell> entry : cells.entrySet()) {
			LandscapeSite currSite = (LandscapeSite) entry.getKey();
			Cell currCell = (Cell) entry.getValue();

			int numWetCorners = 0;
			if (!isNoisy) {
				if (!currSite.isBorder) {
					for (int i = 0; i < currCell.edges.size(); i++) {
						GraphEdge currEdge = currCell.edges.get(i);
						currEdge.corner1.isWater = true;
						numWetCorners++;
					}
					double numWetEdges = numWetCorners / 2.0;
					if (numWetEdges > (currCell.edges.size() / 2.0)) {
						currSite.isLake = true; // set anything wet as a lake by
												// default. We'll turn the
												// outside
												// ones to ocean next
					}
				} else {
					currSite.isLake = true;
					for (int i = 0; i < currCell.edges.size(); i++) {
						GraphEdge currEdge = currCell.edges.get(i);
						currEdge.corner1.isWater = true;
						currEdge.corner2.isWater = true;
						// currEdge.corner1.alt = 0;
						// currEdge.corner2.alt = 0;
					}
				}
			} else {

				if (!currSite.isBorder) {
					// double noise = (float) n.fbm(currSite.x,
					// currSite.y, 0, 2, 0.925f, 200.0f);
					// double noise = n.Perlin_Noise((float) currSite.x /
					// 200000.0f, (float) currSite.y / 200000.0f, 0.10f, 4,
					// .85f, 0.55f);
					// noise *= n.Improved_Noise(currSite.x/30000.0,
					// currSite.y/30000.0, 0);
					// noise /= n.rmf(currSite.x / 50000.0, currSite.y /
					// 50000.0, 0, 4, .85f, 0.55f, 1.0f);

					numWetCorners = 0;

					for (int i = 0; i < currCell.edges.size(); i++) {
						GraphEdge currEdge = currCell.edges.get(i);
						double noise = n.Perlin_Noise((float) currEdge.corner1.x / 200000.0f, (float) currEdge.corner1.y / 200000.0f, 0.10f, 4, .85f, 0.55f);
						noise /= n.rmf(currEdge.corner1.x / 50000.0, currEdge.corner1.y / 50000.0, 0, 4, .85f, 0.55f, 1.0f);
						// System.out.println(Math.abs(noise*1000));
						if (Math.abs(noise * 1000) < 520) {
							currEdge.corner1.isWater = true;
							// currEdge.corner1.alt = 0;
							numWetCorners++;
						} else {
							// currEdge.corner1.alt = Double.MAX_VALUE;
						}
						noise = n.Perlin_Noise((float) currEdge.corner2.x / 200000.0f, (float) currEdge.corner2.y / 200000.0f, 0.10f, 4, .85f, 0.55f);
						noise /= n.rmf(currEdge.corner2.x / 50000.0, currEdge.corner2.y / 50000.0, 0, 4, .85f, 0.55f, 1.0f);
						if (Math.abs(noise * 1000) < 520) {
							currEdge.corner2.isWater = true;
							// currEdge.corner2.alt = 0;
							numWetCorners++;
						} else {
							// currEdge.corner2.alt = Double.MAX_VALUE;
						}
					}
					double numWetEdges = numWetCorners / 2.0;
					if (numWetEdges > (currCell.edges.size() / 2.0)) {
						currSite.isLake = true; // set anything wet as a lake by
						// default. We'll turn the outside
						// ones to ocean next
					}
				} else {
					currSite.isLake = true;
					for (int i = 0; i < currCell.edges.size(); i++) {
						GraphEdge currEdge = currCell.edges.get(i);
						currEdge.corner1.isWater = true;
						currEdge.corner2.isWater = true;
						// currEdge.corner1.alt = 0;
						// currEdge.corner2.alt = 0;
					}
				}

			}
		}
	}

	public void expandBorder() {
		cells = rawOutput.toCells();
		for (Map.Entry<Site, Cell> entry : cells.entrySet()) {
			LandscapeSite currSite = (LandscapeSite) entry.getKey();
			Cell currCell = (Cell) entry.getValue();

			for (int i = 0; i < currCell.edges.size(); i++) {
				GraphEdge currEdge = currCell.edges.get(i);
				LandscapeSite neighborSite;
				if (currEdge.site1 == currSite) {
					neighborSite = ((LandscapeSite) currEdge.site2);
				} else {
					neighborSite = ((LandscapeSite) currEdge.site1);
				}
				if (neighborSite.isBorder || currCell.isWater()) {
					currSite.isLake = true;
					currEdge.corner1.isWater = true;
					currEdge.corner2.isWater = true;
					// currEdge.corner1.alt = 0;
					// currEdge.corner2.alt = 0;
				} else if (!currCell.isWater()) {
					// currEdge.corner1.alt = Double.MAX_VALUE;
					// currEdge.corner2.alt = Double.MAX_VALUE;
				}
			}
		}
	}

	public void uncheckAllCells() {
		cells = rawOutput.toCells();
		for (Map.Entry<Site, Cell> entry : cells.entrySet()) {
			Cell currCell = (Cell) entry.getValue();
			currCell.checked = false;
		}
	}

	public void divideLandAndWater() {
		uncheckAllCells();
		// cells = rawOutput.toCells();
		landCells = new HashMap<Site, Cell>();
		waterCells = new HashMap<Site, Cell>();

		Cell currCell;

		for (Map.Entry<Site, Cell> entry : cells.entrySet()) {
			currCell = (Cell) entry.getValue();
			if (currCell.isWater()) {
				waterCells.put(currCell.site, currCell);
			} else {
				landCells.put(currCell.site, currCell);
			}
		}

		for (Map.Entry<Site, Cell> entry : cells.entrySet()) {
			currCell = (Cell) entry.getValue();
			currCell.checked = true;
			if (((LandscapeSite) currCell.site).isBorder) {
				makeSelfAndWetNeighborsOcean(currCell); // assumes cells are all
														// marked
														// unchecked...
				return;
			}
		}
	}

	public void makeSelfAndWetNeighborsOcean(Cell currCell) {
		((LandscapeSite) currCell.site).isOcean = true;

		Cell nextCell = currCell.findUncheckedNeighbor(cells);
		while (nextCell != null) {
			nextCell.checked = true;
			if (nextCell.isWater()) {
				makeSelfAndWetNeighborsOcean(nextCell);
			}
			nextCell = currCell.findUncheckedNeighbor(cells);
		}
	}

	public void applyElevations() {
		ArrayList<GraphEdge> edges = new ArrayList<GraphEdge>();
		ArrayList<Corner> corners = new ArrayList<Corner>();
		for (Map.Entry<Site, Cell> entry : cells.entrySet()) {
			Cell currCell = (Cell) entry.getValue();
			if (currCell.isWater()) {
				setAllEdgeAlts(currCell, 0);
			} else {
				setAllEdgeAlts(currCell, Double.MAX_VALUE);
			}
			for (int i = 0; i < currCell.edges.size(); i++) {
				GraphEdge currEdge = currCell.edges.get(i);

				if ((((LandscapeSite) currEdge.site1).isOcean && !((LandscapeSite) currEdge.site2).isOcean) || (((LandscapeSite) currEdge.site2).isOcean && !((LandscapeSite) currEdge.site1).isOcean)) {
					currEdge.corner1.isCoast = true;
					currEdge.corner2.isCoast = true;
					currEdge.corner1.alt = 0;
					currEdge.corner2.alt = 0;
				}
				corners.add(currEdge.corner1);
				corners.add(currEdge.corner2);
			}
		}

		int numChanged = 1;
		while (numChanged != 0) {
			System.out.println(corners.size() + "   " + maxAlt + "   " + numChanged);
			numChanged = 0;
			ArrayList<Corner> nextCorners = new ArrayList<Corner>();
			for (int i = 0; i < corners.size(); i++) {
				Corner currCorner = corners.get(i);
				ArrayList<Corner> neighbors = currCorner.getNeighborCorners();
				double minAlt = currCorner.alt;
				for (int j = 0; j < neighbors.size(); j++) {
					minAlt = Math.min(minAlt, neighbors.get(j).alt);
				}
				if (minAlt + 1 < currCorner.alt) {
					currCorner.alt = minAlt + 1;
					numChanged++;
				}
				nextCorners.add(currCorner);
			}
			corners = nextCorners;
		}
		maxAlt = 0;
		for (Map.Entry<Site, Cell> entry : cells.entrySet()) {
			Cell currCell = (Cell) entry.getValue();
			for (int i = 0; i < currCell.edges.size(); i++) {
				if (currCell.edges.get(i).corner1.alt == Double.MAX_VALUE || currCell.edges.get(i).corner2.alt == Double.MAX_VALUE) {
					System.out.println(currCell.edges.get(i).corner1.alt + "   " + currCell.edges.get(i).corner2.alt);
				}
				maxAlt = Math.max(maxAlt, currCell.edges.get(i).corner1.alt);
				maxAlt = Math.max(maxAlt, currCell.edges.get(i).corner2.alt);
			}
		}
	}

	public void applyElevations2() {
		ArrayList<GraphEdge> edges = new ArrayList<GraphEdge>();
		ArrayList<Corner> corners = new ArrayList<Corner>();
		for (Map.Entry<Site, Cell> entry : cells.entrySet()) {
			Cell currCell = (Cell) entry.getValue();
			if (currCell.isWater()) {
				setAllEdgeAlts(currCell, 0);
			} else {
				setAllEdgeAlts(currCell, Double.MAX_VALUE);
			}
			for (int i = 0; i < currCell.edges.size(); i++) {
				GraphEdge currEdge = currCell.edges.get(i);

				if ((((LandscapeSite) currEdge.site1).isOcean && !((LandscapeSite) currEdge.site2).isOcean) || (((LandscapeSite) currEdge.site2).isOcean && !((LandscapeSite) currEdge.site1).isOcean)) {
					currEdge.corner1.isCoast = true;
					currEdge.corner2.isCoast = true;
					currEdge.corner1.alt = 0;
					currEdge.corner2.alt = 0;

					corners.add(currEdge.corner1);
					corners.add(currEdge.corner2);
				}
			}
		}
		int currDistFromOcean = 0;
		while (corners != null) {
			corners = setElevationAsDistFromWater(corners, currDistFromOcean++);
		}
	}

	public void setAllEdgeAlts(Cell currCell, double newAlt) {
		for (int i = 0; i < currCell.edges.size(); i++) {
			currCell.edges.get(i).corner1.alt = newAlt;
			currCell.edges.get(i).corner2.alt = newAlt;
		}
	}

	public ArrayList<Corner> setElevationAsDistFromWater(ArrayList<Corner> cornerList, double currDistFromOcean) {
		double nextDistFromOcean;
		if (currDistFromOcean == 0) {
			nextDistFromOcean = 1;
		} else {
			nextDistFromOcean = (Math.pow(currDistFromOcean, 3)) / 5.0;
		}
		ArrayList<Corner> nextBatch = new ArrayList<Corner>();
		for (int i = 0; i < cornerList.size(); i++) {
			Corner currCorner = cornerList.get(i);
			drawCorners.add(currCorner);
			ArrayList<Corner> neighbors = currCorner.neighbors;
			for (int j = 0; j < neighbors.size(); j++) {
				if (neighbors.get(j).alt >= Double.MAX_VALUE / 2.0) {
					neighbors.get(j).alt = Math.min(neighbors.get(j).alt, nextDistFromOcean);
					// System.out.println("elevating:  " + neighbors.get(j));
					nextBatch.add(neighbors.get(j));
				}
			}
		}
		maxAlt = Math.max(maxAlt, nextDistFromOcean);

		if (nextBatch.size() != cornerList.size()) {
			if (nextBatch.size() > 0) {
				// System.out.println(nextBatch.size() + "   " +
				// cornerList.size());
				return nextBatch;
				// setElevationAsDistFromWater(nextBatch, nextDistFromOcean);
			}
		}
		return null;
	}

	public void determineDownHill() {
		for (Map.Entry<Site, Cell> entry : cells.entrySet()) {
			LandscapeSite currSite = (LandscapeSite) entry.getKey();
			Cell currCell = (Cell) entry.getValue();
			for (int i = 0; i < currCell.edges.size(); i++) {
				GraphEdge currEdge = currCell.edges.get(i);
				if (currEdge.corner1.alt == 0) {
					currEdge.corner1.downhillCorner = null;
				} else {
					currEdge.corner1.downhillCorner = currEdge.corner1.findLowestNeighbor();
				}
				if (currEdge.corner2.alt == 0) {
					currEdge.corner2.downhillCorner = null;
				} else {
					currEdge.corner2.downhillCorner = currEdge.corner2.findLowestNeighbor();
				}
			}
		}
	}

	public void placeRivers(int numRivers) {
		Random generator = new Random();
		Object[] cellArray = landCells.values().toArray();
		for (int i = 0; i < numRivers; i++) {
			int randomIndex = Math.abs(generator.nextInt(cellArray.length));
			Cell randomCell = (Cell) cellArray[randomIndex];
			GraphEdge randomEdge = randomCell.edges.get(generator.nextInt(randomCell.edges.size()));
			Corner lowCorner;
			if (randomEdge.corner1.alt < randomEdge.corner2.alt) {
				recurseRiver(randomEdge.corner1, 1);
			} else {
				recurseRiver(randomEdge.corner2, 1);
			}
		}
	}

	public void recurseRiver(Corner lowCorner, int width) {
		Corner nextCorner = lowCorner.downhillCorner;
		lowCorner.weight += width;
		// lowCorner.alt = Math.max(0,lowCorner.alt-1);

		if (nextCorner != null && !lowCorner.isWater) {
			recurseRiver(nextCorner, width + 1);
		} else {
		}
	}

	public void elevateSites() {
		for (Map.Entry<Site, Cell> entry : cells.entrySet()) {
			Cell currCell = (Cell) entry.getValue();
			LandscapeSite currSite = ((LandscapeSite) currCell.site);
			double avgAlt = 0;
			double minAlt = Double.MAX_VALUE;
			for (int i = 0; i < currCell.edges.size(); i++) {
				GraphEdge currEdge = currCell.edges.get(i);

				if (currEdge.corner1.alt > 2000000) {
					currEdge.corner1.alt = -100;// currEdge.corner2.alt;
					System.out.println("stop");
				}
				if (currEdge.corner2.alt > 2000000) {
					currEdge.corner2.alt = -100;// currEdge.corner1.alt;
					System.out.println("stop");
				}

				double avgEdge = (currEdge.corner1.alt + currEdge.corner2.alt) / 2.0;
				avgAlt += avgEdge;
				minAlt = Math.min(minAlt, currEdge.corner1.alt);
				minAlt = Math.min(minAlt, currEdge.corner2.alt);
			}

			avgAlt /= (double) currCell.edges.size();
			//currSite.alt = avgAlt;
/*
 * if (currSite.isLake) {
 * for (int i = 0; i < currCell.edges.size(); i++) {
 * GraphEdge currEdge = currCell.edges.get(i);
 * currEdge.corner1.alt = minAlt;
 * currEdge.corner2.alt = minAlt;
 * currSite.alt = minAlt;
 * }
 * } else if (!currSite.isOcean) {
 * // currSite.alt = avgAlt;
 * }
 */

		}
	}

	public void populateAllCorners() {
		for (Map.Entry<Site, Cell> entry : cells.entrySet()) {
			Cell currCell = (Cell) entry.getValue();
			LandscapeSite currSite = ((LandscapeSite) currCell.site);

			//putCornerInAllCorners((Corner) currSite);

			for (int i = 0; i < currCell.edges.size(); i++) {
				putCornerInAllCorners(currCell.edges.get(i).corner1);
				putCornerInAllCorners(currCell.edges.get(i).corner2);
			}

		}
	}

	public void putCornerInAllCorners(Corner currCorner) {
		currCorner.snapToGrid(0.01);
		if (!allCorners.containsKey(currCorner.toString())) {
			// System.out.println("new");
			currCorner.glID = allCornerIndex;
			allCorners.put(currCorner.toString(), currCorner);
			allCornerIndex++; // +=6
		} else {
			currCorner.glID = allCorners.get(currCorner.toString()).glID;
		}
		// System.out.println("glID: " + currCorner.glID + "   " +
		// currCorner.toString());
	}

	public void scaleCornerElevations(double scaleFactor) {
		for (Map.Entry<Site, Cell> entry : cells.entrySet()) {
			Cell currCell = (Cell) entry.getValue();

			for (int i = 0; i < currCell.edges.size(); i++) {
				if (!currCell.edges.get(i).corner1.checked) {
					currCell.edges.get(i).corner1.alt *= scaleFactor;
					currCell.edges.get(i).corner1.checked = true;
				}
				if (!currCell.edges.get(i).corner2.checked) {
					currCell.edges.get(i).corner2.alt *= scaleFactor;
					currCell.edges.get(i).corner2.checked = true;
				}
			}
		}

		System.out.println("maxAlt: " + maxAlt);
	}

	public void makeGLTriangleFans(){
		for (Map.Entry<Site, Cell> entry : cells.entrySet()) {
			Cell currCell = (Cell) entry.getValue();

			currCell.makeTriangleFan();
		}
	}
	
	public void computeNormals() {
		for (Map.Entry<Site, Cell> entry : cells.entrySet()) {
			Cell currCell = (Cell) entry.getValue();

			currCell.computeNormal();
		}
		System.out.println("wait here");
/*
 * for (Map.Entry<String, Corner> entry : allCorners.entrySet()) {
 * Corner currCorner = (Corner) entry.getValue();
 * 
 * if(!(currCorner instanceof LandscapeSite)){
 * float[] normal = new float[3];
 * normal[0] = 0;
 * normal[1] = 0;
 * normal[2] = 0;
 * 
 * for(int i = 0; i < currCorner.edges.size(); i++){
 * GraphEdge currEdge = currCorner.edges.get(i);
 * normal[0] += (currEdge.site1.normal[0] + currEdge.site2.normal[0])/2.0f;
 * normal[1] += (currEdge.site1.normal[1] + currEdge.site2.normal[1])/2.0f;
 * normal[2] += (currEdge.site1.normal[2] + currEdge.site2.normal[2])/2.0f;
 * }
 * normal[0] /= currCorner.edges.size();
 * normal[1] /= currCorner.edges.size();
 * normal[2] /= currCorner.edges.size();
 * 
 * currCorner.normal = normal;
 * }
 * }
 */
	}

	public void glScale() {
		for (Map.Entry<Site, Cell> entry : cells.entrySet()) {
			Cell currCell = (Cell) entry.getValue();
			LandscapeSite currSite = (LandscapeSite) currCell.site;
			currSite.x *= GameLogic.GL_SCALE;
			//currSite.alt *= GameLogic.GL_SCALE;
			currSite.y *= GameLogic.GL_SCALE;

			for (int i = 0; i < currCell.edges.size(); i++) {
				GraphEdge currEdge = currCell.edges.get(i);
				currEdge.corner1.x *= GameLogic.GL_SCALE;
				currEdge.corner1.alt *= GameLogic.GL_SCALE;
				currEdge.corner1.y *= GameLogic.GL_SCALE;
				currEdge.corner2.x *= GameLogic.GL_SCALE;
				currEdge.corner2.alt *= GameLogic.GL_SCALE;
				currEdge.corner2.y *= GameLogic.GL_SCALE;
			}
		}
	}

}
